package com.streamer.app.fragment

import android.Manifest
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.Intent
import android.content.pm.PackageManager
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Bundle
import android.os.SystemClock
import android.os.Handler
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Surface
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.WindowManager
import android.graphics.PixelFormat
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.OvershootInterpolator
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import android.net.Uri
import android.widget.VideoView
import androidx.appcompat.widget.SwitchCompat
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.alivc.live.pusher.AlivcLivePusher
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import com.streamer.app.CouponActivity
import com.streamer.app.GiftEffectActivity
import com.streamer.app.LotteryActivity
import com.streamer.app.R
import com.streamer.app.ThreePaneLiveActivity
import com.streamer.app.ThreeScreenLiveActivity
import com.streamer.app.adapter.DanmakuAdapter
import com.streamer.app.adapter.EmojiAdapter
import com.streamer.app.adapter.ProductListAdapter
import com.streamer.app.adapter.ProductPagerAdapter
import com.streamer.app.adapter.UserListAdapter
import com.streamer.app.bean.Item
import com.streamer.app.bean.LiveBean
import com.streamer.app.bean.LiveStats
import com.streamer.app.bean.LoginBean
import com.streamer.app.bean.MessageBean
import com.streamer.app.databinding.FragmentLiveVideoBinding
import com.streamer.app.model.MyViewModel
import com.streamer.app.model.User
import com.streamer.app.model.UserRole
import com.streamer.app.utils.BottomSheetUtils
import com.streamer.app.utils.BottomSheetUtils.showLocalPlayDialog
import com.streamer.app.utils.DialogUtils
import com.streamer.app.utils.DialogUtils.showAnnouncementDialog
import com.streamer.app.utils.MqttManager
import com.streamer.app.utils.ToastUtil
import com.streamer.app.utils.UserManager.getLocalUser
import com.streamer.app.utils.Utils.formatTime

import kotlin.getValue
import kotlin.random.Random

/**
 * ppt 直播
 */
class LiveVideoFragment : BaseFragment<FragmentLiveVideoBinding>(), MqttManager.MessageCallback {

    // 开播前的控件
    private lateinit var btnStartBroadcast: MaterialButton
    private lateinit var topUserSection: ViewGroup
    private lateinit var bottomControlPanel: LinearLayout

    // 直播结束后的控件
    private lateinit var tvTitleEnded: TextView
    private lateinit var centerEndedContent: LinearLayout
    private lateinit var llLiveNotice: LinearLayout
    private lateinit var ivClock: ImageView
    private lateinit var ivAvatar: ImageView
    private lateinit var tvMessage: TextView
    private lateinit var tvStreamerName: TextView
    private lateinit var tvViewerCount: TextView
    private lateinit var tvStreamerNumber: TextView

    // 共用控件
    private lateinit var ivClose: ImageView
    private lateinit var ivMic: ImageView
    private lateinit var ivRecord: ImageView
    private lateinit var ivExitClose: ImageView
    private lateinit var cameraOffBackground: LinearLayout

    // 底部弹窗
    private var bottomSheetDialog: BottomSheetDialog? = null
    private var userListDialog: BottomSheetDialog? = null
    private var productListDialog: BottomSheetDialog? = null
    private var searchDialog: BottomSheetDialog? = null
    private lateinit var tabOnSale: TextView
    private lateinit var tabOffShelf: TextView

    // 自定义表情面板（新方案）
    private var emojiContainer: View? = null
    private var isEmojiPanelVisible = false
    private var totleCount = 0

    // 摄像头相关
    private lateinit var cameraPreviewContainer: FrameLayout
    private var isLiveStreaming = false
    private lateinit var surfaceView: SurfaceView
    private lateinit var surfaceHolder: SurfaceHolder
    private val CAMERA_PERMISSION_REQUEST = 100
    private lateinit var rvDanmaku: RecyclerView
    private lateinit var danmakuAdapter: DanmakuAdapter
    private lateinit var etSend: EditText
    private var isCameraEnabled = true // 跟踪摄像头开关状态
    private var pendingStartPush: Boolean = false
    private var isStartingStream: Boolean = false
    private var lastStartAttemptMs: Long = 0L

    private fun normalizedPushUrl(): String? {
        val raw = mliveData?.pushLiveUrl
        return raw?.replace("artc://", "rtmp://")
    }
    private var videoView: VideoView? = null

    // 是否由用户主动请求外部视频（本地/流媒体）
    private var isExternalVideoRequested = false

    // 是否已开始推流（避免重复 startPush 导致状态异常）
    private var hasStartedPush = false

    // 阿里云直播推流相关（由 ThreePaneLiveActivity 统一管理）
    private var mAlivcLivePusher = AlivcLivePusher()
    private var mLiveUserCount: LoginBean? = null
    private var currentState = State.PRE_LIVE // 当前状态
    private lateinit var ivViewer1: ImageView
    private lateinit var ivViewer2: ImageView
    private lateinit var ivViewer3: ImageView

    private lateinit var tvDisableCount: TextView
    private lateinit var tvBackName: TextView

    // MQTT相关
    private lateinit var mqttManager: MqttManager

    // 点赞相关
    private var consecutiveLikeClicks = 0
    private var likeHandler = Handler()
    private val LIKE_DELAY = 1000L // 1秒延迟

    enum class State {
        PRE_LIVE,    // 开播前
        ON_LIVE, //开播
        LIVE_ENDED   // 直播结束
    }

    private var mliveData: LiveBean? = null

    private val prefs by lazy {
        requireActivity().getSharedPreferences(
            "switch_prefs", MODE_PRIVATE
        )
    }
    private val viewModel: MyViewModel by activityViewModels()
    private var productCountObserversRegistered = false

    override fun initView() {
        // 提前初始化 MQTT，避免点击竞态
        try {
            mqttManager = MqttManager.getInstance()
        } catch (_: Exception) {
        }
        val stateParam = arguments?.getString(EXTRA_LIVE_STATE) ?: STATE_PRE_LIVE
        currentState = when (stateParam) {
            STATE_LIVE_ENDED -> State.LIVE_ENDED
            else -> State.PRE_LIVE
        }


        initViews(_binding.root)
        setupListeners()
        setupTopPadding()
        setupBottomPadding()
        updateUIForState(currentState)
        setupKeyboardHandling()
        viewMode.liveStateLv.observe(requireActivity(), {
            if (it != null) {
                // 不在这里隐藏按钮，让 updateUIForState 来控制
                viewMode.getLiveInfo()
            }
        })
        viewModel.message.observe(viewLifecycleOwner) {
            tabOnSale.text = "售卖中 ($it)"
        }
        viewModel.message2.observe(viewLifecycleOwner) {
            tabOffShelf.text = "已下架 ($it)"

        }

        viewMode.LiveInfoDataLV.observe(viewLifecycleOwner) {
            if (it != null) {
                mliveData = it
                refreshMqttSubscriptions()
            }
        }

        //获取直播回放详细信息
        viewMode.ReplayLV.observe(requireActivity()) {
            if (it != null && isExternalVideoRequested) {
                try {

                    // 停止摄像头预览，显示视频
                    setExternalVideoSourceEnabled(true)
                    ensureVideoView()
                    videoView?.visibility = View.VISIBLE
                    surfaceView.visibility = View.GONE
                    prepareAndStartMediaPlayer(it.liveReplayUrl.toUri())
                } catch (_: Exception) {
                }
            }
        }
        //获取课程内容（视频管理）详细信息
        viewMode.ContentLV.observe(requireActivity()) {
            if (it != null && isExternalVideoRequested) {
                try {

                    // 停止摄像头预览，显示视频
                    setExternalVideoSourceEnabled(true)
                    ensureVideoView()
                    videoView?.visibility = View.VISIBLE
                    surfaceView.visibility = View.GONE
                    prepareAndStartMediaPlayer(it.fileUrl.toUri())
                } catch (_: Exception) {
                }
            }
        }
    }

    private fun setExternalVideoSourceEnabled(enable: Boolean) {
        try {
            Log.d("LiveVideoFragment", "setExternalVideoSourceEnabled($enable)")
            val method = mAlivcLivePusher.javaClass.getMethod(
                "setExternalVideoSource",
                Boolean::class.javaPrimitiveType,
                Boolean::class.javaPrimitiveType,
                Boolean::class.javaPrimitiveType
            )
            method.invoke(mAlivcLivePusher, enable, true, true)
        } catch (_: Exception) {
        }
    }

    private fun prepareAndStartMediaPlayer(uri: Uri) {
        try {
            if (videoView != null) {
                videoView?.setVideoURI(uri)
                videoView?.setOnPreparedListener { mediaPlayer ->
                    mediaPlayer.start()
                    updateLocalPlayProgressUI(mediaPlayer.duration)
                    startProgressUpdater()
                }
                videoView?.start()
            }
        } catch (e: Exception) {
            // 处理异常，例如显示错误提示
            Log.e("VideoView", "Error preparing VideoView", e)
        }
    }

    private fun updateLocalPlayProgressUI(totalMs: Int) {
        val dialog = BottomSheetUtils.getLastLocalPlayDialog() ?: return
        val view = dialog.findViewById<View>(android.R.id.content) ?: return
        val seekBar = view.findViewById<android.widget.SeekBar>(R.id.seekbar_progress) ?: return
        val tvCurrent = view.findViewById<TextView>(R.id.tv_current_time) ?: return
        val tvTotal = view.findViewById<TextView>(R.id.tv_total_time) ?: return

        seekBar.max = totalMs
        tvTotal.text = formatTime(totalMs)
        // 初始当前时间
        tvCurrent.text = formatTime(videoView?.currentPosition ?: 0)

        seekBar.setOnSeekBarChangeListener(object : android.widget.SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(
                seekBar: android.widget.SeekBar?, progress: Int, fromUser: Boolean
            ) {
                if (fromUser) videoView?.seekTo(progress)
            }

            override fun onStartTrackingTouch(seekBar: android.widget.SeekBar?) {}
            override fun onStopTrackingTouch(seekBar: android.widget.SeekBar?) {}
        })
    }

    private fun startProgressUpdater() {
        val dialog = BottomSheetUtils.getLastLocalPlayDialog() ?: return
        val view = dialog.findViewById<View>(android.R.id.content) ?: return
        val seekBar = view.findViewById<android.widget.SeekBar>(R.id.seekbar_progress) ?: return
        val tvCurrent = view.findViewById<TextView>(R.id.tv_current_time) ?: return
        val handler = android.os.Handler(requireActivity().mainLooper)
        val r = object : Runnable {
            override fun run() {
                val pos = videoView?.currentPosition ?: 0
                seekBar.progress = pos
                tvCurrent.text = formatTime(pos)
                if (videoView?.visibility == View.VISIBLE) handler.postDelayed(this, 500)
            }
        }
        handler.post(r)
    }

    private fun initViews(view: View) {


        ivViewer1 = view.findViewById(R.id.iv_viewer_1)
        ivViewer2 = view.findViewById(R.id.iv_viewer_2)
        ivViewer3 = view.findViewById(R.id.iv_viewer_3)
        ivExitClose = view.findViewById(R.id.iv_exit_close)
        cameraOffBackground = view.findViewById(R.id.camera_off_background)

        viewMode.LiveInfoLV.observe(requireActivity()) {
            if (it != null) {
                mliveData = it
                //获取直播间历史评论
                viewMode.messageHistory(it?.liveRoomNo.toString())
//                直播状态 0:未开始, 1:直播中, 2:已结束
                when (it.useState) {
                    0 -> {
                        currentState = State.PRE_LIVE
                        updateUIForState(currentState)
                    }

                    1 -> {
                        currentState = State.ON_LIVE
                        updateUIForState(currentState)
                        startLiveStream()
                    }

                    2 -> {
                        currentState = State.LIVE_ENDED
                        updateUIForState(currentState)
                    }
                }
                viewMode.liveUserCount(mliveData?.id.toString())
                setupMqtt()
                // 检查MQTT连接状态
                if (mqttManager.isConnected()) {
                    startLiveStream()
                    // 触发 PPTWhiteboardFragment 开始录制
                    val threePaneActivity =
                        requireActivity() as? com.streamer.app.ThreeScreenLiveActivity
                    val threeScreenActivity =
                        requireActivity() as? com.streamer.app.ThreeScreenLiveActivity
                    threePaneActivity?.triggerWhiteboardRecording(mliveData?.pushLive3PUrl.toString())
                        ?: threeScreenActivity?.triggerWhiteboardRecording(mliveData?.pushLive3PUrl.toString())
                } else {
                    // 重新连接MQTT
                    val random6Digit = Random.nextInt(100000, 1000000)
                    mqttManager.connect(
                        requireActivity(),
                        "${mliveData?.liveRoomNo + "," + mliveData?.id + "," + getLocalUser()?.id + ",5" + "," + random6Digit}"
                    ) { success, _ ->
                        requireActivity().runOnUiThread {
                            if (success) {
                                startLiveStream()
                                // 触发 PPTWhiteboardFragment 开始录制
                                val threePaneActivity =
                                    requireActivity() as? com.streamer.app.ThreeScreenLiveActivity
                                val threeScreenActivity =
                                    requireActivity() as? com.streamer.app.ThreeScreenLiveActivity
                                threePaneActivity?.triggerWhiteboardRecording(mliveData?.pushLive3PUrl.toString())
                                    ?: threeScreenActivity?.triggerWhiteboardRecording(mliveData?.pushLive3PUrl.toString())
                            }
                        }
                    }
                }
            }
        }
        ivExitClose.setOnClickListener {

            // 初始化弹幕列表
        }
        rvDanmaku = view.findViewById(R.id.rv_danmaku)
        danmakuAdapter = DanmakuAdapter(mutableListOf())
        rvDanmaku.apply {
            layoutManager = LinearLayoutManager(requireActivity()).apply {
                stackFromEnd = true
            }
            adapter = danmakuAdapter
        }
        // 历史消息/新消息观察
        viewMode.MessageListLV.observe(requireActivity()) { result ->
            result?.data?.let { list ->
                danmakuAdapter.setAll(list)
                rvDanmaku.scrollToPosition(danmakuAdapter.itemCount - 1)
            }
        }

        // 开播前控件
        btnStartBroadcast = view.findViewById(R.id.btn_start_broadcast)
        topUserSection = view.findViewById(R.id.top_user_section)
        bottomControlPanel = view.findViewById(R.id.bottom_control_panel)

        // 直播结束控件
        tvTitleEnded = view.findViewById(R.id.tv_title_ended)
        centerEndedContent = view.findViewById(R.id.center_ended_content)
        ivClock = view.findViewById(R.id.iv_clock)
        ivAvatar = view.findViewById(R.id.iv_streamer_avatar)
        tvMessage = view.findViewById(R.id.tv_message)
        tvStreamerName = view.findViewById(R.id.tv_streamer_name)
        tvViewerCount = view.findViewById(R.id.tv_viewer_count)
        tvStreamerNumber = view.findViewById(R.id.tv_streamer_number)
        llLiveNotice = view.findViewById(R.id.llLiveNotice)

        // 摄像头预览容器
        cameraPreviewContainer = view.findViewById(R.id.camera_preview_container)

        // 初始化SurfaceView - 使用普通SurfaceView实现全屏显示
        surfaceView = SurfaceView(requireActivity())
        surfaceHolder = surfaceView.holder
        // 提升渲染稳定性
        surfaceHolder.setFormat(PixelFormat.RGBA_8888)
        surfaceView.keepScreenOn = true
        // 发送输入框 IME 回车发送
        etSend = view.findViewById(R.id.etSend)



        etSend.setOnEditorActionListener { v, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_SEND) {
                val text = etSend.text?.toString()?.trim().orEmpty()
                if (text.isNotEmpty()) {
                    viewMode.send(text, mliveData?.id.toString())

                    rvDanmaku.scrollToPosition(danmakuAdapter.itemCount - 1)
                    etSend.setText("")
                }
                true
            } else {
                false
            }
        }
        surfaceHolder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                Log.d(
                    "LiveVideoFragment",
                    "Surface created, isLiveStreaming=" + isLiveStreaming + " pendingStartPush=" + pendingStartPush + " externalRequested=" + isExternalVideoRequested
                )
                try {
                    if (isLiveStreaming) {
                        // 启动预览
                        Log.d("LiveVideoFragment", "surfaceCreated: startPreview(surfaceView)")
                        mAlivcLivePusher.startPreview(surfaceView)
                        // 如有待启动推流，继续推流
                        if (pendingStartPush && !normalizedPushUrl().isNullOrEmpty() && !hasStartedPush && !isStartingStream) {
                            surfaceView.postDelayed({
                                try {
                                    val url = normalizedPushUrl()
                                    Log.d("LiveVideoFragment", "surfaceCreated: startPush(" + url + ")")
                                    mAlivcLivePusher.startPush(url)
                                    hasStartedPush = true
                                } catch (_: Exception) {
                                }
                            }, 150)
                        }
                        pendingStartPush = false
                    }
                } catch (e: Exception) {
                    Log.e(
                        "LiveVideoFragment",
                        "Error starting preview on surfaceCreated: ${e.message}"
                    )
                }
            }

            override fun surfaceChanged(
                holder: SurfaceHolder, format: Int, width: Int, height: Int
            ) {
                Log.d("LiveVideoFragment", "Surface changed: " + width + "x" + height)
            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                Log.d("LiveVideoFragment", "Surface destroyed")
            }
        })

        // 将SurfaceView添加到容器中
        cameraPreviewContainer.addView(surfaceView)

        // 设置SurfaceView的布局参数，实现全屏显示
        val layoutParams = FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
        )
        layoutParams.gravity = Gravity.CENTER
        surfaceView.layoutParams = layoutParams

        // 设置SurfaceView的ZOrder，确保摄像头预览在最上层
        surfaceView.setZOrderOnTop(false)
        // 预览层保持普通层，避免合成冻结
        surfaceView.setZOrderMediaOverlay(false)

        // 根据固定比例(16:9)调整Surface的实际缓冲区尺寸，避免拉伸
        surfaceView.addOnLayoutChangeListener { _, left, top, right, bottom, _, _, _, _ ->
            val width = right - left
            val height = bottom - top
            // 优先做中心裁剪（cover），确保显示区域不变形
            updateSurfaceLayoutCenterCrop(width, height)
            // 同步缓冲区尺寸到接近16:9，减少缩放失真
            adjustSurfaceFixedSize(width, height)
        }

        // 共用控件
        ivClose = view.findViewById(R.id.iv_close)
        ivMic = view.findViewById(R.id.iv_mic)
        ivRecord = view.findViewById(R.id.iv_record)

        // 观众头像列表点击事件
        val llListAudienceAvatar = view.findViewById<LinearLayout>(R.id.llListAudienceAvatar)
        llListAudienceAvatar.setOnClickListener {
            viewMode.liveUserCount(mliveData?.id.toString())

            showUserListDialog()
        }

        llLiveNotice.setOnClickListener {
            viewMode.getLastLiveNotice()
        }
        viewMode.LiveNoteTips.observe(requireActivity()) {
            if (it != null) {
                showAnnouncementDialog(requireActivity(), "公告", it.toString())
            }
        }

        ivAvatar.apply {
            Glide.with(requireActivity()).load(getLocalUser()?.avatar).circleCrop().into(this)

            tvStreamerName.text = getLocalUser()?.nickName
        }

        viewMode.LiveUserCountLV.observe(requireActivity()) {
            if (it != null) {
                mLiveUserCount = it
                if (::tvDisableCount.isInitialized) {
                    // 已经初始化，可以安全使用
                    tvDisableCount.text = "禁言名单(${mLiveUserCount?.disableCount.toString()})"
                }
                if (::tvBackName.isInitialized) {
                    tvBackName.text = "踢出房间名单(${mLiveUserCount?.defriendCount.toString()})"
                }
                tvViewerCount.text = it.liveCount.toString() + "人"
                tvStreamerNumber.text = it.popularity.toString() + "点赞"
            }
        }

    }


    private fun startLiveStream() {
        try {
            Log.d("LiveVideoFragment", "startLiveStream called")
            // Debounce 和重入保护，避免页面刷新触发多次
            val now = SystemClock.uptimeMillis()
            if (hasStartedPush) {
                Log.d("LiveVideoFragment", "startLiveStream: already pushing, skip")
                return
            }
            if (isStartingStream && now - lastStartAttemptMs < 1500L) {
                Log.d("LiveVideoFragment", "startLiveStream: already starting, debounce skip")
                return
            }
            isStartingStream = true
            lastStartAttemptMs = now
            if (!checkCameraPermission()) {
                requestCameraPermission()
                return
            }
            if (!checkMicrophonePermission()) {
                requestCameraPermission()
                return
            }

            // 确保推流器初始化
            if (!isLiveStreaming) {
                mAlivcLivePusher.init(requireActivity(), mAlivcLivePushConfig)
                isLiveStreaming = true
            }

            // 显示预览容器
            cameraPreviewContainer.visibility = View.VISIBLE
            ivExitClose.visibility = View.GONE

            val surface = surfaceHolder.surface
            if (surface == null || !surface.isValid) {
                Log.d("LiveVideoFragment", "startLiveStream: surface invalid, wait surfaceCreated")
                // Surface 未就绪，等待 surfaceCreated 再启动
                if (!pendingStartPush) pendingStartPush = true else Log.d(
                    "LiveVideoFragment", "startLiveStream: pendingStartPush already true"
                )
                isStartingStream = false
                return
            }

            // 确保使用相机源（关闭外部源）
            setExternalVideoSourceEnabled(false)

            // 立即启动预览（若已存在旧预览，先安全停止再启动）
            try {
                mAlivcLivePusher.stopPreview()
            } catch (_: Exception) {
            }
            // 确保 Surface 挂在窗口上再启动，避免黑屏
            surfaceView.post {
                try {
                    mAlivcLivePusher.startPreview(surfaceView)
                } catch (_: Exception) {
                }
            }

            // 稍作延时启动推流
            surfaceView.postDelayed({
                try {
                    val url = normalizedPushUrl()
                    if (!url.isNullOrEmpty() && !hasStartedPush) {
                        Log.d("LiveVideoFragment", "startLiveStream: startPush(" + url + ")")
                        mAlivcLivePusher.startPush(url)
                        hasStartedPush = true
                        // 推流后不再操作预览，避免 PUSHED 状态被拒导致黑屏
                    } else {
                        Log.e("LiveVideoFragment", "Push URL is empty")
                    }
                } catch (_: Exception) {
                }
            }, 150)
            // 启动流程结束，允许后续再次调用
            isStartingStream = false
        } catch (e: Exception) {
            Log.e("LiveVideoFragment", "Error in startLiveStream: ${e.message}")
            ToastUtil.toastShortMessage("开启直播失败")
        } finally {
            // 如果已经安排了等待 surface 或者已经推流，会有相应标志控制
            if (hasStartedPush) isStartingStream = false
        }
    }

    // 轻踢醒：重启预览，清理本地合成管线中的冻结帧
    private fun safeKickPreview() {
        try {
            Log.d("LiveVideoFragment", "kickPreview(): setExternalVideoSourceEnabled(false)")
            setExternalVideoSourceEnabled(false)
            Log.d("LiveVideoFragment", "kickPreview(): stopPreview -> startPreview -> resume")
            try {
                mAlivcLivePusher.stopPreview()
            } catch (_: Exception) {
            }
            mAlivcLivePusher.startPreview(surfaceView)
            if (isCameraEnabled) {
                Log.d("LiveVideoFragment", "kickPreview(): resume")
                try {
                    mAlivcLivePusher.resume()
                } catch (_: Exception) {
                }
            }
        } catch (_: Exception) {
        }
    }

    // 延迟重建 Surface：彻底清掉冻结帧（不影响已在推流）
    private fun rebuildPreviewSurface() {
        try {
            val parent = cameraPreviewContainer
            val old = surfaceView
            val idx = parent.indexOfChild(old)
            if (idx >= 0) {
                parent.removeViewAt(idx)
                val newSurface = SurfaceView(requireActivity())
                surfaceHolder = newSurface.holder
                surfaceHolder.setFormat(PixelFormat.RGBA_8888)
                newSurface.keepScreenOn = true
                newSurface.layoutParams = old.layoutParams
                parent.addView(newSurface, idx)
                surfaceView = newSurface
                // 重新绑定回调
                surfaceHolder.addCallback(object : SurfaceHolder.Callback {
                    override fun surfaceCreated(holder: SurfaceHolder) {
                        try {
                            mAlivcLivePusher.startPreview(surfaceView)
                            if (isCameraEnabled) mAlivcLivePusher.resume()
                        } catch (_: Exception) {
                        }
                    }

                    override fun surfaceChanged(
                        holder: SurfaceHolder, format: Int, width: Int, height: Int
                    ) {
                    }

                    override fun surfaceDestroyed(holder: SurfaceHolder) {}
                })
            }
        } catch (_: Exception) {
        }
    }

    private fun setupListeners() {
        btnStartBroadcast.setOnClickListener {
            btnStartBroadcast.visibility = View.GONE
            viewMode.startLive()


        }

        ivClose.setOnClickListener {
            DialogUtils.showEndLiveMuteConfirmDialog(requireActivity(), {
                viewMode.endLive()
            })
        }
        viewMode.EndLiveLV.observe(requireActivity()) {
            if (it != null) {
                endLiveStream()
                (context as ThreeScreenLiveActivity).endLive()
            }
        }

        ivMic.setOnClickListener {
            showBottomSheet()
        }

        // 点赞按钮
        ivRecord.setOnClickListener {
            playLikeAnimation(ivRecord)
            consecutiveLikeClicks++
            likeHandler.removeCallbacksAndMessages(null)
            likeHandler.postDelayed({
                if (consecutiveLikeClicks > 0) {
                    viewMode.like(consecutiveLikeClicks.toString())
                    consecutiveLikeClicks = 0
                }
            }, LIKE_DELAY)
        }

        // emoji按钮点击事件
        val tvIcon = _binding.tvIcon
        tvIcon.setOnClickListener {
            toggleEmojiPanel()
        }

        // 美颜按钮点击事件
        val ivBeauty = _binding.ivBeauty
        ivBeauty.setOnClickListener {

            showProductListDialog()
        }
        viewMode.CoursewareListLV.observe(requireActivity()) { coursewareData ->
            coursewareData?.let {
                coursewareList.clear()
                coursewareList.addAll(it)
                Log.d("WhiteboardFragment", "课件列表数据更新，共 ${it.size} 个文件")
            }
        }

    }

    private fun endLiveStream() {
        try {
            if (isLiveStreaming) {


                // 停止阿里云直播推流
                mAlivcLivePusher?.stopPreview()
                mAlivcLivePusher?.stopPush()
                mAlivcLivePusher?.destroy()

                // 隐藏摄像头预览
                cameraPreviewContainer.visibility = View.GONE

                // 显示开播按钮
                btnStartBroadcast.visibility = View.VISIBLE

                isLiveStreaming = false
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        // 发送直播结束状态到MQTT
        publishLiveStatus("ended")

        currentState = State.LIVE_ENDED
        updateUIForState(currentState)
        ToastUtil.toastShortMessage("直播已结束")
    }

    private fun updateUIForState(state: State) {
        when (state) {
            State.PRE_LIVE -> {
                // 显示开播前的UI
                btnStartBroadcast.visibility = View.VISIBLE
                topUserSection.visibility = View.VISIBLE
                bottomControlPanel.visibility = View.VISIBLE
                llLiveNotice.visibility = View.VISIBLE

                // 隐藏结束状态的UI
                tvTitleEnded.visibility = View.GONE
                centerEndedContent.visibility = View.GONE
            }

            State.LIVE_ENDED -> {
                // 隐藏开播前的UI
                btnStartBroadcast.visibility = View.GONE
                topUserSection.visibility = View.GONE
                bottomControlPanel.visibility = View.GONE
                llLiveNotice.visibility = View.GONE

                // 显示结束状态的UI
                tvTitleEnded.visibility = View.GONE
                centerEndedContent.visibility = View.VISIBLE
                ivExitClose.visibility = View.VISIBLE
            }

            State.ON_LIVE -> {
                btnStartBroadcast.visibility = View.GONE
            }
        }
//        endLiveStream()
    }

    private fun setupTopPadding() {
        // 为开播前的顶部用户区域设置动态间距
        ViewCompat.setOnApplyWindowInsetsListener(topUserSection) { view, insets ->
            val statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top

            // 自定义顶部间距：基础间距 + 状态栏高度
            val basePadding = 16 // dp
            val basePaddingPx = (basePadding * resources.displayMetrics.density).toInt()
            val totalTopPadding = basePaddingPx + statusBarHeight

            view.setPadding(
                view.paddingLeft, totalTopPadding, view.paddingRight, view.paddingBottom
            )

            insets
        }

        // 为直播结束状态的标题设置动态间距
        ViewCompat.setOnApplyWindowInsetsListener(tvTitleEnded) { view, insets ->
            val statusBarHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top

            // 自定义顶部间距：基础间距 + 状态栏高度
            val basePadding = 16 // dp
            val basePaddingPx = (basePadding * resources.displayMetrics.density).toInt()
            val totalTopPadding = basePaddingPx + statusBarHeight

            view.setPadding(
                view.paddingLeft, totalTopPadding, view.paddingRight, view.paddingBottom
            )

            insets
        }
    }

    private fun setupBottomPadding() {
        // 设置WindowInsets监听来获取系统导航栏高度
        ViewCompat.setOnApplyWindowInsetsListener(bottomControlPanel) { view, insets ->
            val navigationBarHeight =
                insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom

            // 自定义底部间距：基础间距 + 导航栏高度
            val basePadding = 32 // dp
            val basePaddingPx = (basePadding * resources.displayMetrics.density).toInt()
            val totalBottomPadding = basePaddingPx + navigationBarHeight

            // 设置底部间距
            view.setPadding(
                view.paddingLeft, view.paddingTop, view.paddingRight, totalBottomPadding
            )

            insets
        }
    }

    private fun showBottomSheet() {
        viewMode.getCoursewareInfo()
        viewMode.getLiveData()
        if (bottomSheetDialog == null) {
            bottomSheetDialog = BottomSheetDialog(requireActivity())
            val bottomSheetView = layoutInflater.inflate(R.layout.bottom_sheet_more, null)
            bottomSheetDialog?.setContentView(bottomSheetView)

            // 设置弹窗属性
            bottomSheetDialog?.setCancelable(true)
            bottomSheetDialog?.setCanceledOnTouchOutside(true)

            // 设置底部弹窗的控件监听
            setupBottomSheetListeners(bottomSheetView)
        }

        bottomSheetDialog?.show()
    }

    private fun setupBottomSheetListeners(view: View) {
        // 关闭按钮
        view.findViewById<ImageView>(R.id.iv_close_bottom_sheet).setOnClickListener {
            bottomSheetDialog?.dismiss()
        }

        // 摄像头前后切换按钮
        val tvFront = view.findViewById<TextView>(R.id.tvFront)
        val tvAfter = view.findViewById<TextView>(R.id.tvAfter)

        // 默认选中前置摄像头
        tvFront.background = requireActivity().getDrawable(R.drawable.view_select_on)
        tvFront.setTextColor(requireActivity().getColor(R.color.white))
        tvAfter.background = requireActivity().getDrawable(R.drawable.view_select_off)
        tvAfter.setTextColor(requireActivity().getColor(R.color.gray))

        tvFront.setOnClickListener {
            // 选中前摄像头
            tvFront.background = requireActivity().getDrawable(R.drawable.view_select_on)
            tvFront.setTextColor(requireActivity().getColor(R.color.white))
            tvAfter.background = requireActivity().getDrawable(R.drawable.view_select_off)
            tvAfter.setTextColor(requireActivity().getColor(R.color.gray))
            switchCamera("1") // 前置摄像头
            Toast.makeText(requireActivity(), "切换到前置摄像头", Toast.LENGTH_SHORT).show()
        }

        tvAfter.setOnClickListener {
            // 选中后摄像头
            tvAfter.background = requireActivity().getDrawable(R.drawable.view_select_on)
            tvAfter.setTextColor(requireActivity().getColor(R.color.white))
            tvFront.background = requireActivity().getDrawable(R.drawable.view_select_off)
            tvFront.setTextColor(requireActivity().getColor(R.color.gray))
            switchCamera("0") // 后置摄像头
            Toast.makeText(requireActivity(), "切换到后置摄像头", Toast.LENGTH_SHORT).show()
        }

        // 摄像头切换开关
        view.findViewById<SwitchCompat>(R.id.switch_camera)
            .setOnCheckedChangeListener { _, isChecked ->
                if (isChecked) {
                    // 恢复摄像头预览和推流
                    // 确保预览已启动
                    val surface = surfaceHolder.surface
                    if (surface != null && surface.isValid) {
                        // 确保在下一帧再启动预览，避免 Surface 尚未 ready 导致黑屏
                        surfaceView.post {
                            try {
                                mAlivcLivePusher.startPreview(surfaceView)
                            } catch (_: Exception) {
                            }
                        }
                    } else {
                        pendingStartPush = true
                    }
                    // 恢复推流
                    try {
                        mAlivcLivePusher.resume()
                    } catch (_: Exception) {
                    }
                    // 更新状态并隐藏暂停覆盖层
                    isCameraEnabled = true
                    cameraOffBackground.visibility = View.GONE

                } else {
                    // 暂停摄像头预览和推流
                    // 暂停推流（保持预览但停止推流）
                    mAlivcLivePusher.pause()
                    // 更新状态并显示暂停覆盖层
                    isCameraEnabled = false
                    cameraOffBackground.visibility = View.VISIBLE

                }
            }

        // 麦克风开关
        view.findViewById<SwitchCompat>(R.id.switch_microphone)
            .setOnCheckedChangeListener { _, isChecked ->
                mAlivcLivePusher?.setMute(!isChecked)
            }

        // 底部按钮点击事件
        view.findViewById<LinearLayout>(R.id.btn_lottery).setOnClickListener {
            val intent = Intent(requireActivity(), LotteryActivity::class.java)
            intent.putExtra("roomId", mliveData?.id.toString())
            startActivity(intent)
            bottomSheetDialog?.dismiss()
        }

        view.findViewById<LinearLayout>(R.id.btn_coupon).setOnClickListener {
            val intent = Intent(requireActivity(), CouponActivity::class.java)
            intent.putExtra("roomId", mliveData?.id.toString())

            startActivity(intent)
            bottomSheetDialog?.dismiss()
        }

        view.findViewById<LinearLayout>(R.id.btn_announcement).setOnClickListener {
            BottomSheetUtils.showAnnouncementBottomSheet(requireActivity()) { content ->
                // 这里可以处理发布后的逻辑
                Toast.makeText(requireActivity(), "发布公告: $content", Toast.LENGTH_SHORT).show()
                viewMode.pushLiveNotice("", content, mliveData?.id.toString())

            }
        }
        //课件
        view.findViewById<LinearLayout>(R.id.btn_courseware).setOnClickListener {
            showCoursewareDialogWithData(
                context = requireActivity(),
                coursewareList = coursewareList,
                onFileSelectedListener = { fileName ->
                    // 处理文件选择
                    val contents = fileName.conversionContent
                    val hasPages = contents.isNotEmpty()
                    try {
                        val activity = requireActivity() as ThreeScreenLiveActivity
                        val wbFrag =
                            activity.supportFragmentManager.findFragmentById(R.id.container_whiteboard)
                        if (wbFrag is PPTWhiteboardFragment) {
                            // 将列表传给白板，并令其显示第一页
                            wbFrag.requireActivity().runOnUiThread {
                                wbFrag.viewMode.CoursewareInfoLV.value = mutableListOf(fileName)
                            }
                        }
                    } catch (_: Exception) {
                    }

                },
                onAddFileClick = { mimeTypes: Array<String> ->
                    // 启动系统文件选择器
                    openDocumentLauncher.launch(mimeTypes)
                },
                {
                    // 删除课件回调：转发给白板进行清空
                    try {
                        val activity = requireActivity() as ThreeScreenLiveActivity
                        val wbFrag =
                            activity.supportFragmentManager.findFragmentById(R.id.container_whiteboard)
                        if (wbFrag is PPTWhiteboardFragment) {
                            wbFrag.requireActivity().runOnUiThread {
                                wbFrag.viewMode.CoursewareInfoLV.value = mutableListOf()
                            }
                        }
                    } catch (_: Exception) {
                    }
                })
        }

        //插播
        view.findViewById<LinearLayout>(R.id.btn_play).setOnClickListener {
            // 打开插播弹窗。弹窗内的列表点击，已在 BottomSheetUtils 中回调到
            showLocalPlayDialog(requireActivity(), mliveData?.interstitialVideoUrl)
        }

        viewMode.PushLiveNoticeLV.observe(requireActivity()) {
            if (it != null) {
                bottomSheetDialog?.dismiss()
            }
        }

        view.findViewById<LinearLayout>(R.id.btn_gift_forward).setOnClickListener {
            val intent = Intent(requireActivity(), GiftEffectActivity::class.java)
            intent.putExtra("roomId", mliveData?.id.toString())
            startActivity(intent)
        }

    }

    // ====== 插播：视频与摄像头切换（供 Activity/弹窗回调调用） ======
    fun playLocalVideo(uri: Uri) {
        try {
            Log.d("LiveVideoFragment", "playLocalVideo uri=$uri")
            isExternalVideoRequested = true
            stopVideoPlaybackIfAny()
            ensureVideoView()
            videoView?.visibility = View.VISIBLE
            surfaceView.visibility = View.GONE
            // 播放本地视频时启用外部源，避免与相机源竞争
            try {
                setExternalVideoSourceEnabled(true)
            } catch (_: Exception) {
            }
            // 暂停推流摄像头本地预览，避免资源争抢
            try {
                mAlivcLivePusher?.pause()
            } catch (_: Exception) {
            }
            videoView?.setVideoURI(uri)
            videoView?.setOnPreparedListener { mp ->
                mp.start()
            }
            videoView?.start()
        } catch (_: Exception) {
        }
    }


    fun playSteamVideo(uri: Item) {
        try {
            Log.d("LiveVideoFragment", "playSteamVideo item=$uri")
            isExternalVideoRequested = true
            if (uri.type == 1) {
                viewMode.replay(uri.id)
            } else {
                viewMode.content(uri.id)

            }
        } catch (_: Exception) {
        }
    }

    fun showCameraPreview() {
        try {
            Log.d("LiveVideoFragment", "showCameraPreview()")
            isExternalVideoRequested = false
            stopVideoPlaybackIfAny()
            surfaceView.visibility = View.VISIBLE
            videoView?.visibility = View.GONE
            // 回到相机预览：关闭外部源，重启预览并恢复推流
            try {
                setExternalVideoSourceEnabled(false)
            } catch (_: Exception) {
            }
            try {
                Log.d("LiveVideoFragment", "showCameraPreview(): stopPreview")
                mAlivcLivePusher.stopPreview()
            } catch (_: Exception) {
            }
            try {
                Log.d("LiveVideoFragment", "showCameraPreview(): startPreview(surfaceView)")
                mAlivcLivePusher.startPreview(surfaceView)
            } catch (_: Exception) {
            }
            try {
                Log.d("LiveVideoFragment", "showCameraPreview(): resume")
                mAlivcLivePusher.resume()
            } catch (_: Exception) {
            }
        } catch (_: Exception) {
        }
    }

    private fun ensureVideoView() {
        if (videoView == null) {
            videoView = VideoView(requireActivity())
            val lp = FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
            )
            lp.gravity = Gravity.CENTER
            videoView?.layoutParams = lp
            cameraPreviewContainer.addView(videoView)
        }
    }

    private fun stopVideoPlaybackIfAny() {
        try {
            videoView?.let { vv ->
                if (vv.isPlaying) vv.stopPlayback()
            }
        } catch (_: Exception) {
        }
    }

    fun pickLocalVideoAndRefresh(dialog: com.google.android.material.bottomsheet.BottomSheetDialog) {
        // 启动系统文件选择器选择视频文件
        val mimeTypes = arrayOf("video/*")
        openDocumentLauncher.launch(mimeTypes)
        // 注意：文件选择的结果会在 BaseFragment 的 openDocumentLauncher 回调中处理
        // 选择完成后会自动刷新插播列表
    }

    @SuppressLint("MissingInflatedId")
    private fun showUserListDialog() {
        // 调用API获取用户列表数据
        viewMode.pageQuery(mliveData?.id.toString(), pageSize, currentPage)
        if (userListDialog == null) {
            userListDialog = BottomSheetDialog(requireActivity())
            val userListView = layoutInflater.inflate(R.layout.bottom_sheet_user_list, null)
            userListDialog?.setContentView(userListView)

            // 设置弹窗属性
            userListDialog?.setCancelable(true)
            userListDialog?.setCanceledOnTouchOutside(true)

            // 防止滑动关闭
            userListDialog?.behavior?.isDraggable = false
            userListDialog?.behavior?.isHideable = false

            tvDisableCount = userListView.findViewById<TextView>(R.id.tvDisableCount).apply {
                text = "禁言名单(${mLiveUserCount?.disableCount.toString()})"
            }
            tvBackName = userListView.findViewById<TextView>(R.id.tvBackName).apply {
                text = "踢出房间名单(${mLiveUserCount?.defriendCount.toString()})"
            }
            // 设置用户列表弹窗的控件监听
            setupUserListListeners(userListView)
        }

        userListDialog?.show()
    }

    private fun setupUserListListeners(view: View) {
        // 关闭按钮
        view.findViewById<ImageView>(R.id.iv_close_user_list).setOnClickListener {
            userListDialog?.dismiss()
        }

        // 设置点击外部关闭
        userListDialog?.setOnCancelListener {
            // 点击外部关闭
        }

        // 设置RecyclerView
        val recyclerView = view.findViewById<RecyclerView>(R.id.rv_user_list)
        recyclerView.layoutManager = LinearLayoutManager(requireActivity())

        // 设置滑动冲突处理
        recyclerView.isNestedScrollingEnabled = true
        recyclerView.overScrollMode = View.OVER_SCROLL_NEVER
        viewMode.PublishCouponLV.observe(requireActivity()) {
            // 刷新商品列表数据
            viewMode.pageQuery(mliveData?.id.toString(), pageSize, currentPage)
            viewMode.liveUserCount(mliveData?.id.toString())

            // 如果商品列表弹窗已显示，刷新商品数量
            if (productListDialog?.isShowing == true) {
                // 延迟一下确保数据更新完成
                Handler().postDelayed({
                    // 这里需要调用刷新数量的方法，但需要从setupProductListListeners中提取出来
                    refreshProductCountsInDialog()
                }, 500)
            }
        }

        // 创建适配器（初始为空列表）
        val adapter = UserListAdapter(
            users = mutableListOf(), onUserAction = { user, action ->
                when (action) {
                    "mute" -> {
                        Toast.makeText(requireActivity(), "禁言 ${user.name}", Toast.LENGTH_SHORT)
                            .show()
                        viewMode.userDisable(user.id)

                    }

                    "unmute" -> {
                        viewMode.userDisable(user.id)

                        ToastUtil.toastShortMessage("解除禁言 ${user.name}")
                    }


                    "kick" -> {
                        viewMode.userDefriend(user.id)
//                        Toast.makeText(requireActivity(), "踢出房间 ${user.name}", Toast.LENGTH_SHORT)
//                            .show()

                    }

                    "blacklist" -> {
                        viewMode.blacklist(user.id)

                        ToastUtil.toastShortMessage("加入黑名单 ${user.name}")

                    }

                }
            }, isMutedList = false
        )
        recyclerView.adapter = adapter

        // 观察API返回的数据
        viewMode.LiveUserListLV.observe(requireActivity()) { liveUserList ->
            if (liveUserList != null && liveUserList.isNotEmpty()) {
                // 将API数据转换为User对象
                val users = mutableListOf<User>()
                tvViewerCount.text = liveUserList.size.toString() + "人"
                if (liveUserList.isEmpty()) {
                    ivViewer1.visibility = View.GONE
                    ivViewer2.visibility = View.GONE
                    ivViewer3.visibility = View.GONE
                } else {
                    ivViewer1.apply {
                        Glide.with(this).load(liveUserList[0]?.avatar.toString())
                            .transform(RoundedCorners(50)).into(this)
                    }
                    if (liveUserList.size > 3) {
                        ivViewer2.apply {
                            Glide.with(this).load(liveUserList[1]?.avatar.toString())
                                .transform(RoundedCorners(50)).into(this)
                        }
                        ivViewer2.apply {
                            Glide.with(this).load(liveUserList[2]?.avatar.toString())
                                .transform(RoundedCorners(50)).into(this)
                        }
                    }

                }
                // 转换API返回的LiveUserBean为User对象
                liveUserList.forEach { liveUser ->
                    val userRole = when (liveUser.userType) {
                        1 -> UserRole.ASSISTANT  // 助教
                        2 -> UserRole.ASSISTANT  // 销售
                        3 -> UserRole.VIEWER     // 外部用户
                        4 -> UserRole.VIEWER     // 虚拟用户
                        5 -> UserRole.STREAMER   // 主播
                        else -> UserRole.VIEWER
                    }

                    val user = User(
                        id = liveUser.id,
                        name = liveUser.userNick,
                        avatar = liveUser.avatar, // 默认头像，实际应该从API获取
                        role = userRole,
                        isMuted = liveUser.disable, // 是否禁言（禁言名单）
                        isKicked = liveUser.defriend, // 是否被踢出房间
                        isBlacklisted = liveUser.blacklist, // 是否被加入黑名单
                        joinTime = liveUser.joinTime // 加入时间
                    )
                    users.add(user)

                }

                // 更新适配器数据
                adapter.updateUsers(users)
            } else {
                // 如果API返回空数据，显示默认用户（主播）
                val defaultUsers = mutableListOf(
                    User(
                        getLocalUser()?.id.toString(),
                        getLocalUser()?.nickName.toString(),
                        getLocalUser()?.avatar.toString(),
                        UserRole.STREAMER
                    )
                )
                adapter.updateUsers(defaultUsers)
            }
        }

        // 观察禁言用户列表数据（移到外部，避免重复注册）
        viewMode.LiveDisableUserListLV.observe(requireActivity()) { disableUserList ->
            if (disableUserList != null && disableUserList.isNotEmpty()) {
                // 将API数据转换为User对象
                val mutedUsers = disableUserList.map { liveUser ->
                    val userRole = when (liveUser.userType) {
                        1 -> UserRole.ASSISTANT  // 助教
                        2 -> UserRole.ASSISTANT  // 销售
                        3 -> UserRole.VIEWER     // 外部用户
                        4 -> UserRole.VIEWER     // 虚拟用户
                        5 -> UserRole.STREAMER   // 主播
                        else -> UserRole.VIEWER
                    }

                    User(
                        id = liveUser.id,
                        name = liveUser.userNick,
                        avatar = liveUser.avatar,
                        role = userRole,
                        isMuted = liveUser.disable,
                        isKicked = liveUser.defriend,
                        isBlacklisted = liveUser.blacklist,
                        joinTime = liveUser.joinTime
                    )
                }

                // 显示禁言名单弹窗
                BottomSheetUtils.showMutedListDialog(
                    context = requireActivity(),
                    mutedUsers = mutedUsers,
                    onUnmuteUser = { user ->
                        // 调用解除禁言API
                        viewMode.userDisable(user.id)
                        Toast.makeText(
                            requireActivity(), "解除禁言: ${user.name}", Toast.LENGTH_SHORT
                        ).show()
                    },
                    onUnmuteAll = {
                        // 批量解除禁言
                        mutedUsers.forEach { user ->
                            viewMode.userDisable(user.id)
                        }
                        Toast.makeText(requireActivity(), "全部解禁", Toast.LENGTH_SHORT).show()
                    })
            } else {
                // 如果没有禁言用户，显示空状态
                Toast.makeText(requireActivity(), "暂无禁言用户", Toast.LENGTH_SHORT).show()
            }
        }

        // 观察踢出用户列表数据（移到外部，避免重复注册）
        viewMode.LiveDefriendUserListLV.observe(requireActivity()) { defriendUserList ->
            if (defriendUserList != null && defriendUserList.isNotEmpty()) {
                // 将API数据转换为User对象
                val kickedUsers = defriendUserList.map { liveUser ->
                    val userRole = when (liveUser.userType) {
                        1 -> UserRole.ASSISTANT  // 助教
                        2 -> UserRole.ASSISTANT  // 销售
                        3 -> UserRole.VIEWER     // 外部用户
                        4 -> UserRole.VIEWER     // 虚拟用户
                        5 -> UserRole.STREAMER   // 主播
                        else -> UserRole.VIEWER
                    }

                    User(
                        id = liveUser.id,
                        name = liveUser.userNick,
                        avatar = liveUser.avatar,
                        role = userRole,
                        isMuted = liveUser.disable,
                        isKicked = liveUser.defriend,
                        isBlacklisted = liveUser.blacklist,
                        joinTime = liveUser.joinTime
                    )
                }

                // 显示踢出名单弹窗
                BottomSheetUtils.showKickedListDialog(
                    context = requireActivity(),
                    kickedUsers = kickedUsers,
                    onUnmuteUser = { user ->
                        // 调用恢复用户API
                        viewMode.userDefriend(user.id)
                        Toast.makeText(
                            requireActivity(), "恢复用户: ${user.name}", Toast.LENGTH_SHORT
                        ).show()
                    },
                    onUnmuteAll = {
                        // 批量恢复用户
                        kickedUsers.forEach { user ->
                            viewMode.userDefriend(user.id)
                        }
                        Toast.makeText(requireActivity(), "全部恢复", Toast.LENGTH_SHORT).show()
                    })
            } else {
                // 如果没有踢出用户，显示空状态
                Toast.makeText(requireActivity(), "暂无踢出用户", Toast.LENGTH_SHORT).show()
            }
        }

        // 底部操作栏
        view.findViewById<View>(R.id.btn_muted_list).setOnClickListener {
            // 调用API获取禁言用户列表
            viewMode.pageQuery(mliveData?.id.toString(), pageSize, currentPage, disable = true)
        }

        //踢出黑名单
        view.findViewById<View>(R.id.btn_kicked_list).setOnClickListener {
            // 调用API获取踢出用户列表
            viewMode.pageQuery(mliveData?.id.toString(), pageSize, currentPage, defriend = true)
        }
    }

    private fun showProductListDialog() {
        if (productListDialog == null) {
            productListDialog = BottomSheetDialog(requireActivity())
            val productListView = layoutInflater.inflate(R.layout.bottom_sheet_product_list, null)

            // 设置商品弹出框的高度
            val displayMetrics = resources.displayMetrics
            val screenHeight = displayMetrics.heightPixels
            val dialogHeight = (screenHeight * 0.7).toInt() // 设置为屏幕高度的70%

            val layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight
            )
            productListView.layoutParams = layoutParams

            productListDialog?.setContentView(productListView)

            // 设置弹窗属性
            productListDialog?.setCancelable(true)
            productListDialog?.setCanceledOnTouchOutside(true)

            // 设置商品列表弹窗的控件监听
            setupProductListListeners(productListView)
        }

        productListDialog?.show()
    }

    private fun setupProductListListeners(view: View) {
        // ViewPager设置
        val viewPager = view.findViewById<androidx.viewpager2.widget.ViewPager2>(R.id.view_pager)
        val pagerAdapter = ProductPagerAdapter(requireActivity(), mliveData?.id.toString() ?: "")
        viewPager.adapter = pagerAdapter

        // 标签页切换
        tabOnSale = view.findViewById<TextView>(R.id.tab_on_sale)
        tabOffShelf = view.findViewById<TextView>(R.id.tab_off_shelf)

        // 指示器
        val indicator1 = view.findViewById<View>(R.id.indicator_1)
        val indicator2 = view.findViewById<View>(R.id.indicator_2)
        registerProductCountObserversIfNeeded()
        updateProductCounts()

        // 显示售卖中商品
        fun showOnSaleProducts() {
            tabOnSale.setTextColor(requireActivity().getColor(R.color.black))
            tabOnSale.textSize = 16f
            tabOnSale.setTypeface(null, android.graphics.Typeface.BOLD)

            tabOffShelf.setTextColor(requireActivity().getColor(R.color.gray))
            tabOffShelf.textSize = 16f
            tabOffShelf.setTypeface(null, android.graphics.Typeface.NORMAL)

            viewPager.currentItem = 0

            // 更新指示器
            indicator1.setBackgroundResource(R.drawable.indicator_active)
            indicator2.setBackgroundResource(R.drawable.indicator_inactive)
        }

        // 显示已下架商品
        fun showOffShelfProducts() {
            tabOffShelf.setTextColor(requireActivity().getColor(R.color.blue_primary))
            tabOffShelf.textSize = 16f
            tabOffShelf.setTypeface(null, android.graphics.Typeface.BOLD)

            tabOnSale.setTextColor(requireActivity().getColor(R.color.gray))
            tabOnSale.textSize = 16f
            tabOnSale.setTypeface(null, android.graphics.Typeface.NORMAL)

            viewPager.currentItem = 1

            // 更新指示器
            indicator1.setBackgroundResource(R.drawable.indicator_inactive)
            indicator2.setBackgroundResource(R.drawable.indicator_active)
        }

        // 设置标签页点击事件
        tabOnSale.setOnClickListener {
            showOnSaleProducts()
        }

        tabOffShelf.setOnClickListener {
            showOffShelfProducts()
        }

        // ViewPager页面切换监听
        viewPager.registerOnPageChangeCallback(object :
            androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                when (position) {
                    0 -> showOnSaleProducts()
                    1 -> showOffShelfProducts()
                }
            }
        })

        // 获取商品数量并更新标签页（只拉取数据，不重复注册观察者）
        updateProductCounts()

        // 默认显示售卖中商品
        showOnSaleProducts()

        // 搜索按钮点击事件
        val searchLayout = view.findViewById<LinearLayout>(R.id.search_layout)
        val switchShoppingCart = view.findViewById<SwitchCompat>(R.id.switch_shopping_cart)
        searchLayout.setOnClickListener {
            showSearchDialog()
        }
        //开关调用小黄车接口
        switchShoppingCart.setOnCheckedChangeListener { _, isChecked ->

            viewMode.closeOpenYellowCar()
        }
        if (mliveData?.isYellowCarEnabled == true) {
            switchShoppingCart.isChecked = false
        } else {
            switchShoppingCart.isChecked = true

        }

        // 设置点击外部关闭
        productListDialog?.setOnCancelListener {
            // 点击外部关闭
        }
    }

    fun updateProductCounts() {
        // 仅触发拉取，观察者只注册一次
        viewMode.getOnSaleProductCount(mliveData?.id.toString() ?: "")
        viewMode.getOffShelfProductCount(mliveData?.id.toString() ?: "")
    }

    private fun registerProductCountObserversIfNeeded() {
        if (productCountObserversRegistered) return
        productCountObserversRegistered = true

        viewMode.OnSaleProductCountLV.observe(viewLifecycleOwner) { onSaleCount ->
            Log.d("xxxx", "售卖中商品数量: $onSaleCount")
            if (::tabOnSale.isInitialized) {

                tabOnSale.text = "售卖中 ($onSaleCount)"
            }
        }
        viewMode.OffShelfProductCountLV.observe(viewLifecycleOwner) { offShelfCount ->
            Log.d("xxxx", "已下架商品数量: $offShelfCount")
            if (::tabOffShelf.isInitialized) {
                tabOffShelf.text = "已下架 ($offShelfCount)"
            }
        }
    }

    private fun showSearchDialog() {
        if (searchDialog == null) {
            searchDialog = BottomSheetDialog(requireActivity())
            val searchView =
                LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_product_search, null)

            // 设置搜索弹出框的高度与商品弹出框一致
            val displayMetrics = resources.displayMetrics
            val screenHeight = displayMetrics.heightPixels
            val dialogHeight = (screenHeight * 0.7).toInt() // 设置为屏幕高度的70%

            val layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight
            )
            searchView.layoutParams = layoutParams

            searchDialog?.setContentView(searchView)

            // 设置弹窗属性
            searchDialog?.setCancelable(true)
            searchDialog?.setCanceledOnTouchOutside(true)

            // 获取搜索输入框
            val etSearch = searchView.findViewById<EditText>(R.id.et_search)

            etSearch.setOnEditorActionListener { v, actionId, _ ->
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    val text = etSearch.text?.toString()?.trim().orEmpty()
                    viewMode.liveProductsPageQuery(
                        pageSize, currentPage, mliveData?.id.toString() ?: "", "", text
                    )

                    true

                } else {
                    false
                }
            }
            val tvResultCount = searchView.findViewById<TextView>(R.id.tv_result_count)
            val rvProduct = searchView.findViewById<RecyclerView>(R.id.rvProduct)
            val tvEmpty = searchView.findViewById<TextView>(R.id.tvEmpty)
            val ivBack = searchView.findViewById<ImageView>(R.id.ivBack)

            // 设置RecyclerView
            rvProduct.layoutManager = LinearLayoutManager(requireActivity())
            val searchAdapter = ProductListAdapter(mutableListOf(), true) { product, action ->
                // 处理搜索结果中的商品操作
                when (action) {
                    "view_product" -> {
                        // 显示商品详情
                        Toast.makeText(
                            requireActivity(), "查看商品: ${product.title}", Toast.LENGTH_SHORT
                        ).show()
                    }
                }
            }
            rvProduct.adapter = searchAdapter

            // 观察搜索结果
            viewMode.liveProductBeanLV.observe(requireActivity()) { result ->
                if (result?.rows != null && result.rows.isNotEmpty()) {
                    val productList = result.rows
                    searchAdapter.updateProducts(productList)
                    tvResultCount.text = "搜到${result.total}条相关数据"
                    rvProduct.visibility = View.VISIBLE
                    tvEmpty.visibility = View.GONE
                } else {
                    searchAdapter.updateProducts(emptyList())
                    tvResultCount.text = "搜到0条相关数据"
                    rvProduct.visibility = View.GONE
                    tvEmpty.visibility = View.VISIBLE
                }
            }

            // 搜索按钮
            searchView.findViewById<ImageView>(R.id.iv_search).setOnClickListener {
                val keyword = etSearch.text.toString().trim()
                if (keyword.isNotEmpty()) {
                    // 执行搜索
                    viewMode.liveProductsPageQuery(
                        pageSize, currentPage, mliveData?.id.toString() ?: "", "", keyword
                    )
                } else {
                    Toast.makeText(requireActivity(), "请输入搜索关键词", Toast.LENGTH_SHORT).show()
                }
            }

            // 返回按钮
            ivBack.setOnClickListener {
                searchDialog?.dismiss()
            }

            // 设置点击外部关闭
            searchDialog?.setOnCancelListener {
                // 点击外部关闭
            }
        }

        searchDialog?.show()
    }


    fun switchCamera(cameraId: String) {
        mAlivcLivePusher.switchCamera()
    }


    private fun toggleEmojiPanel() {
        if (isEmojiPanelVisible) {
            hideEmojiPanel()
        } else {
            showEmojiPanel()
        }
    }

    private fun showEmojiPanel() {
        // 收起系统键盘
        val imm =
            requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(etSend.windowToken, 0)

        if (emojiContainer == null) {
            val root = requireActivity().findViewById<ViewGroup>(android.R.id.content)
            val panelView = layoutInflater.inflate(R.layout.bottom_sheet_emoji, root, false)
            // 使用布局文件中定义的高度，而不是硬编码
            val panelHeight = (400 * resources.displayMetrics.density).toInt()
            val lp = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, panelHeight)
            lp.gravity = Gravity.BOTTOM
            panelView.layoutParams = lp

            // 设置数据
            val llMostUsed = panelView.findViewById<LinearLayout>(R.id.ll_most_used)
            val rvAllEmojis = panelView.findViewById<RecyclerView>(R.id.rv_all_emojis)
            val mostUsedEmojis = listOf(
                "\uD83D\uDE04",
                "\uD83D\uDE06",
                "\uD83D\uDE02",
                "\uD83E\uDD23",
                "\uD83D\uDE0D",
                "\uD83E\uDD70",
                "\uD83D\uDE0E",
                "\uD83E\uDD14",
            )
            val allEmojis = listOf(
                "😊",
                "😘",
                "🥺",
                "😠",
                "🤭",
                "😭",
                "😡",
                "😄",
                "😅",
                "😌",
                "😜",
                "😝",
                "🐕",
                "❤️",
                "🤏",
                "👏",
                "🙏",
                "🤗",
                "🌹",
                "😅",
                "🤩",
                "⭐",
                "👤",
                "🤔",
                "🥺",
                "🙂"
            )
            llMostUsed.removeAllViews()
            mostUsedEmojis.forEach { emoji ->
                val tv = TextView(requireActivity()).apply {
                    text = emoji
                    textSize = 24f
                    gravity = Gravity.CENTER
                    setPadding(16, 16, 16, 16)
                    background =
                        requireActivity().getDrawable(android.R.drawable.list_selector_background)
                    setOnClickListener {
                        insertEmojiToInput(emoji)
                        hideEmojiPanel()
                    }
                }
                val p = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
                p.setMargins(4, 4, 4, 4)
                llMostUsed.addView(tv, p)
            }
            rvAllEmojis.layoutManager = GridLayoutManager(requireActivity(), 6)
            rvAllEmojis.adapter = EmojiAdapter(allEmojis) { emoji ->
                insertEmojiToInput(emoji)
                hideEmojiPanel()
            }
            // 强制RecyclerView重新测量和布局
            rvAllEmojis.requestLayout()
            // 添加到根布局
            root.addView(panelView)
            emojiContainer = panelView
        }

        // 上推输入栏到面板之上
        val panelHeight = (emojiContainer?.layoutParams?.height ?: 0)
        bottomControlPanel.animate().translationY(-panelHeight.toFloat()).setDuration(200)
            .setInterpolator(AccelerateDecelerateInterpolator()).start()
        emojiContainer?.visibility = View.VISIBLE
        isEmojiPanelVisible = true
    }

    private fun hideEmojiPanel() {
        emojiContainer?.let { view ->
            view.visibility = View.GONE
        }
        bottomControlPanel.animate().translationY(0f).setDuration(200)
            .setInterpolator(AccelerateDecelerateInterpolator()).start()
        isEmojiPanelVisible = false
    }

    /**
     * 将emoji插入到输入框
     */
    private fun insertEmojiToInput(emoji: String) {
        val currentText = etSend.text.toString()
        val cursorPosition = etSend.selectionStart
        val newText =
            currentText.substring(0, cursorPosition) + emoji + currentText.substring(cursorPosition)
        etSend.setText(newText)
        etSend.setSelection(cursorPosition + emoji.length)

        // 确保输入框获得焦点
        etSend.requestFocus()
    }

    // 刷新商品列表弹窗中的商品数量
    private fun refreshProductCountsInDialog() {
        if (productListDialog?.isShowing == true) {
            // 延迟一下确保数据更新完成
            Handler().postDelayed({
                // 重新获取商品数量，触发数据更新
                viewMode.getOnSaleProductCount(mliveData?.id.toString() ?: "")
                viewMode.getOffShelfProductCount(mliveData?.id.toString() ?: "")
            }, 500)
        }
    }


    private fun setupKeyboardHandling() {
        // 设置软键盘模式 - 调整布局大小
        requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

        // 监听软键盘状态变化
        val rootView = view?.findViewById<View>(android.R.id.content)
        rootView?.viewTreeObserver?.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            private var lastHeight = 0

            override fun onGlobalLayout() {
                val currentHeight = rootView.height
                if (lastHeight != 0 && currentHeight != lastHeight) {
                    val heightDifference = lastHeight - currentHeight
                    if (heightDifference > 200) {
                        // 软键盘弹出
                        Log.d("", "Soft keyboard shown")
                        handleKeyboardShown()
                        // 键盘弹出时隐藏 emoji 面板，避免冲突
                        if (isEmojiPanelVisible) hideEmojiPanel()
                    } else if (heightDifference < -200) {
                        // 软键盘隐藏
                        Log.d("", "Soft keyboard hidden")
                        handleKeyboardHidden()
                    }
                }
                lastHeight = currentHeight
            }
        })

        // 设置输入框焦点变化监听
        etSend.setOnFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                // 输入框获得焦点时，确保底部控制栏可见
                bottomControlPanel.post {
                    bottomControlPanel.requestLayout()
                }
            }
        }
    }

    private fun handleKeyboardShown() {
        // 软键盘弹出时的处理
        requireActivity().runOnUiThread {
            // 滚动弹幕列表到底部，确保最新消息可见
            rvDanmaku.post {
                rvDanmaku.scrollToPosition(danmakuAdapter.itemCount - 1)
            }

            // 可以在这里添加其他UI调整
        }
    }

    private fun handleKeyboardHidden() {
        // 软键盘隐藏时的处理

    }

    // ==================== MQTT 相关方法 ====================

    private fun setupMqtt() {
        // 改为使用 BaseFragment 生命周期统一订阅；全局连接在宿主初始化
        mqttManager = MqttManager.getInstance()
        mqttManager.addMessageCallback(this)
        refreshMqttSubscriptions()
    }

    override fun mqttTopics(): List<String> {
        val liveRoomNo = mliveData?.id ?: return emptyList()
        return listOf("chat/$liveRoomNo")
    }

    override fun onMqttMessage(topic: String, payload: String) {
        handleLiveMessage(payload)
    }

    private fun subscribeToLiveTopics() { /* handled by BaseFragment */
    }

    // MQTT消息回调
    override fun onMessageReceived(topic: String, message: String) {

        requireActivity().runOnUiThread {
            handleLiveMessage(message)
        }
    }

    override fun onConnectionStatusChanged(connected: Boolean) {
        Log.d("", "MQTT connection status changed: $connected")

    }


    private fun handleLiveMessage(message: String) {
        try {
            val gson = Gson()
            val chatMessage = gson.fromJson(message, MessageBean::class.java)

            when (chatMessage.type) {
                1 -> { /* JOIN(1) - 进入房间 */
                }

                2 -> { /* LEAVE(2) - 离开房间 */
                }

                3 -> { // MSG(3) - 普通消息
                    // 过滤系统统计等JSON内容，避免显示为聊天气泡
                    val contentText = chatMessage.content?.toString() ?: ""
                    val trimmed = contentText.trim()
                    val looksJson =
                        trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed.contains("defriendCount") || trimmed.contains(
                            "disableCount"
                        ) || trimmed.contains("popularity")

                    if (!looksJson && chatMessage.range == 0) {
                        danmakuAdapter.append(chatMessage)
                        // 滚动到最新消息
                        rvDanmaku.post {
                            rvDanmaku.scrollToPosition(danmakuAdapter.itemCount - 1)
                        }
                    }
                }

                4 -> { /* SYSTEM(4) - 系统消息 */
                }

                5 -> { /* DRAW(5) - 抽奖倒计时 */
                }

                6 -> { /* COUPON(6) - 优惠券倒计时 */
                }

                7 -> { /* TAUGHT(7) - 商品讲解 */
                }

                8 -> { /* NOTICE(8) - 公告 */
                }

                9 -> { /* COUPON_RECEIVE(9) - 优惠券领取 */
                }

                10 -> { /* DRAW_USER(10) - 抽奖完成通知 */
                }

                11 -> { /* MSG_CONCEAL(11) - 消息隐藏 */
                }

                12 -> { /* BESTOW_GIFT(12) - 赠送礼物 */
                }

                13 -> { /* DEFRIEND(13) - 踢出直播间 */
                }

                14 -> { /* POINTS_ACQUISITION(14) - 获取积分 */
                }

                15 -> { /* CANCEL_TAUGHT(15) - 取消讲解 */
                }

                16 -> { /* LIKE(16) - 点赞 */
                    tvStreamerNumber.text = chatMessage.content.toString() + "点赞"

                }

                17 -> { /* PUTAWAY(17) - 商品上架 */
                }

                18 -> { /* CONFIG_STATUS_UPDATE(18) - 直播配置状态更新 */
                }

                19 -> { /* THE_USER_IS_BUYING(19) - 正在购买商品 */
                }

                20 -> { /* POPULARITY(20) - 直播间人气推送 */
                    val gson = Gson()
                    val liveStats = gson.fromJson(chatMessage.content, LiveStats::class.java)
                    tvViewerCount.text = liveStats.liveCount.toString() + "人"
                }

                else -> { /* 未知类型 */
                }
            }

        } catch (e: JsonSyntaxException) {
        } catch (e: Exception) {
        }
    }

    // 发送直播状态到MQTT
    private fun publishLiveStatus(status: String) {
        val liveRoomNo = mliveData?.liveRoomNo ?: ""
        val message = """
            {
                "status": "$status",
                "liveRoomNo": "$liveRoomNo",
                "timestamp": ${System.currentTimeMillis()},
                "device": "android"
            }
        """.trimIndent()

        mqttManager.publish("live/$liveRoomNo/status", message) { success, result ->
            Log.d("LiveVideoFragment", "Publish live status result: $success, $result")
            if (success) {
                Log.d("LiveVideoFragment", "Live status published successfully")
            } else {
                Log.e("LiveVideoFragment", "Failed to publish live status: $result")
            }
        }
    }


    override fun onDestroy() {
        super.onDestroy()

        // 移除MQTT回调
        mqttManager.removeMessageCallback(this)

        // 发送直播结束状态
        publishLiveStatus("end")

        // 相机/推流由 Activity 释放，这里不额外处理
    }


    private fun checkCameraPermission(): Boolean = ContextCompat.checkSelfPermission(
        requireActivity(), Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED

    private fun checkMicrophonePermission(): Boolean {
        return ContextCompat.checkSelfPermission(
            requireActivity(), Manifest.permission.RECORD_AUDIO
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun requestCameraPermission() {
        ActivityCompat.requestPermissions(
            requireActivity(),
            arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO),
            CAMERA_PERMISSION_REQUEST
        )
    }

    @Deprecated("Deprecated in Java")
    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == CAMERA_PERMISSION_REQUEST) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (isLiveStreaming) {
                    val surface = surfaceHolder.surface
                    if (surface != null && surface.isValid) {
                        if (pendingStartPush) {
                            try {
                                mAlivcLivePusher?.startPreview(surfaceView)
                                val url = normalizedPushUrl()
                                if (!url.isNullOrEmpty()) {
                                    surfaceView.postDelayed({
                                        try {
                                            mAlivcLivePusher?.startPush(url)
                                        } catch (_: Exception) {
                                        }
                                    }, 150)
                                }
                            } catch (_: Exception) {
                            } finally {
                                pendingStartPush = false
                            }
                        }
                    }
                }
            } else {
                Toast.makeText(requireActivity(), "需要摄像头权限才能开启直播", Toast.LENGTH_SHORT)
                    .show()
            }
        }
    }

    // 以16:9为目标比例做center-crop，避免画面拉伸
    private fun adjustSurfaceFixedSize(viewWidth: Int, viewHeight: Int) {
        if (viewWidth <= 0 || viewHeight <= 0) return

        // 获取摄像头支持的预览尺寸
        val cameraManager =
            requireActivity().getSystemService(Context.CAMERA_SERVICE) as android.hardware.camera2.CameraManager
        val cameraId = "1" // 默认前置摄像头

        try {
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)

            if (map != null) {
                val previewSizes = map.getOutputSizes(android.graphics.SurfaceTexture::class.java)
                if (previewSizes.isNotEmpty()) {
                    // 选择最接近16:9比例的预览尺寸
                    val targetRatio = 16f / 9f
                    var bestSize = previewSizes[0]
                    var minDiff = Float.MAX_VALUE

                    for (size in previewSizes) {
                        val ratio = size.width.toFloat() / size.height.toFloat()
                        val diff = Math.abs(ratio - targetRatio)
                        if (diff < minDiff) {
                            minDiff = diff
                            bestSize = size
                        }
                    }

                    // 使用选中的预览尺寸设置Surface
                    try {
                        surfaceHolder.setFixedSize(bestSize.width, bestSize.height)
                        Log.d("Camera", "Set surface size: ${bestSize.width}x${bestSize.height}")
                        return
                    } catch (e: Exception) {
                        Log.e("Camera", "Failed to set surface size: ${e.message}")
                    }
                }
            }
        } catch (e: Exception) {
            Log.e("Camera", "Error getting camera characteristics: ${e.message}")
        }

        // 如果无法获取摄像头预览尺寸，使用默认的16:9比例计算
        val targetRatio = 16f / 9f
        val viewRatio = viewWidth.toFloat() / viewHeight.toFloat()

        var bufferWidth: Int
        var bufferHeight: Int
        if (viewRatio > targetRatio) {
            // 视图更"宽"，以高度为基准计算宽度
            bufferHeight = viewHeight
            bufferWidth = (bufferHeight * targetRatio).toInt()
        } else {
            // 视图更"高"，以宽度为基准计算高度
            bufferWidth = viewWidth
            bufferHeight = (bufferWidth / targetRatio).toInt()
        }

        if (bufferWidth > 0 && bufferHeight > 0) {
            try {
                surfaceHolder.setFixedSize(bufferWidth, bufferHeight)
                Log.d("Camera", "Set fallback surface size: ${bufferWidth}x${bufferHeight}")
            } catch (e: Exception) {
                Log.e("Camera", "Failed to set fallback surface size: ${e.message}")
            }
        }
    }

    // 将 SurfaceView 以 16:9 中心裁剪铺满容器，避免半屏时的拉伸或压缩
    private fun updateSurfaceLayoutCenterCrop(containerWidth: Int, containerHeight: Int) {
        if (containerWidth <= 0 || containerHeight <= 0) return
        val targetRatio = 16f / 9f
        val containerRatio = containerWidth.toFloat() / containerHeight.toFloat()

        var displayWidth: Int
        var displayHeight: Int

        if (containerRatio > targetRatio) {
            // 容器更宽，为了cover：以高度为基准放大宽度
            displayHeight = containerHeight
            displayWidth = (displayHeight * targetRatio).toInt()
        } else {
            // 容器更高或等比，为了cover：以宽度为基准放大高度
            displayWidth = containerWidth
            displayHeight = (displayWidth / targetRatio).toInt()
        }

        val lp = surfaceView.layoutParams as FrameLayout.LayoutParams
        if (lp.width != displayWidth || lp.height != displayHeight || lp.gravity != Gravity.CENTER) {
            lp.width = displayWidth
            lp.height = displayHeight
            lp.gravity = Gravity.CENTER
            surfaceView.layoutParams = lp
        }
    }

    private fun playLikeAnimation(target: View) {
        val scaleUpX = ObjectAnimator.ofFloat(target, View.SCALE_X, 1f, 1.35f)
        val scaleUpY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 1f, 1.35f)
        val scaleDownX = ObjectAnimator.ofFloat(target, View.SCALE_X, 1.35f, 1f)
        val scaleDownY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 1.35f, 1f)
        val set = AnimatorSet()
        set.play(scaleUpX).with(scaleUpY)
        set.play(scaleDownX).with(scaleDownY).after(scaleUpX)
        set.duration = 180
        set.interpolator = OvershootInterpolator(2f)
        set.start()
    }

    companion object {
        const val EXTRA_LIVE_STATE = "live_state"
        const val STATE_PRE_LIVE = "pre_live"
        const val STATE_LIVE_ENDED = "live_ended"
        fun newInstance(): LiveVideoFragment {
            return LiveVideoFragment()
        }
    }
}
